<?php
	//GREP:VIEWIFY
	if (!defined("EXPONENT")) exit("");
	if (!defined("SYS_SEARCH")) include_once(BASE."subsystems/search.php");
	//8/27/2009: immanuel192 write this code to calculate how long the search perform
	$query_time_start=microtime();
	// end 8/27/2009
	global $router;
	// First, check our module config
	$config = $db->selectObject('searchmodule_config',"location_data='".serialize($loc)."'");
	if ($config == null) {
		$config->is_categorized = 0;
		// 10/12/2009: immanuel192 add this line
		$config->modules=null; 
	}
	$config->timeout=15*60; // 15 minutes
	$config->max_item= 15; // how many items each page 

	//8/27/2009 Immanuel192 write this code to support query_id parameter passthrought
	$query_id=0;
	if (isset($_REQUEST['query_id'])){
		$query_id=intval($_REQUEST['query_id']);
		$temp=$db->selectObject("search_cache","(id={$query_id}) AND (lang = '".LANG."')");
		if ($temp){
			$_REQUEST['search_string'] = $temp->query;
		}
	}
	
	$modules=getModuleNames(unserialize($config->modules));
	$modules_list=array();
	foreach ($modules as $key=>$value){
		$temp_module=null;
		$temp_module->id=$key;
		$temp_module->name=$value;
		$temp_module->checked=0;
		$modules_list[]=$temp_module;
	}

	if (isset($_REQUEST['modules'])) {
		$modules = $_REQUEST['modules'];
		// change checked state 
		foreach ($modules as $key=>$value){
			// search in $modules_list to find correct id
			foreach ($modules_list as $k=>$v){
				if ($v->id == $value){
					$v->checked=1;
					$modules_list[$k]=$v;
					break; 
				}
			}
		}
	} elseif (!isset($config->modules) && !isset($_REQUEST['modules'])) {
		//$modules = array();
		$modules=array_keys($modules);
	} else {
		$modules = unserialize($config->modules);
	}
	// end 8/27/2009
	if (!isset($_REQUEST['search_string'])) $_REQUEST['search_string']='';
	$search_string = trim(strip_tags($_REQUEST['search_string']));


	if ($search_string == "") {
		echo exponent_lang_loadKey('modules/searchmodule/actions/search.php','need_term');
		return;
	}

	$term_status = exponent_search_cleanSearchQuery(
	@array_map("addslashes",array_map("trim",split(" ",$search_string)))
	);

	$terms = $term_status['valid'];

	$results = array();
	// 8/26/2009: Immanuel192 write this code to cache
	// get page
	$page=1;
	if (isset($_REQUEST['page']))
		$page=intval($_REQUEST['page']);
	//clear all old search cache
	$now=time();
	$temp=$db->selectObjects("search_cache","search_time+{$config->timeout} < {$now}");
	foreach ($temp as $key=>$value){
		// clear result_cache
		$db->delete("search_cache_result","query_id = {$value->id}");
		$db->delete("search_cache","id = {$value->id}");
	}
	// do we need to search again?
	$temp=$db->selectObject("search_cache","search_time+{$config->timeout} > {$now} AND query = '{$search_string}'");
	$search_cache=null;
	$search=null;
	// check if $_REQUEST['research'] =1 => do the search again
	if (isset($_REQUEST['research']) && ($_REQUEST['research']==1) && $temp){
		// clean old search cache
		$db->delete("search_cache_result","query_id = {$temp->id}");
		$db->delete("search_cache","id = {$temp->id}");
		unset($temp);
	}
	if (isset($temp)){
		// reload again search result
		$search_cache=null;
		$search_cache=$temp; // get search cache
		$search=-1; // flag to reload the cache
	}
	else {
		// we need to search again
		// get search_type
		$search_type=SEARCH_TYPE_ANY;
		if (isset($_REQUEST['search_type']))
		{
			$_REQUEST['search_type']=intval($_REQUEST['search_type']);
			if ($_REQUEST['search_type'] == 1)
				$search_type=SEARCH_TYPE_ANY;
			else
				if ($_REQUEST['search_type'] == 2)
					$search_type=SEARCH_TYPE_PHRASE;
		}
		//
		$search=$db->selectObjects("search",exponent_search_whereClause(array("title","body","keywords"),$terms,$modules, $search_type) . " AND (lang = '".LANG."') ORDER BY category, id" );
		// save the search query id
		$search_cache=null;
		$search_cache->result_count = count($search);
		$search_cache->query=$search_string;
        $search_cache->search_time=$now;
		$search_cache->lang=LANG;
		//$search_id=0;
		$search_id=$db->insertObject($search_cache,"search_cache");
		$search_cache->id=$search_id;
		// write to cache
		// build sql query
		// set page=1 and return only first max_item
		$page=1; $search_cache_query=""; $search_temp=array(); 
        
        // to get better performance when calculate weight, we should pre-change case of terms to lower
        $terms_lower=array();
        foreach ($terms as $k=>$v)
            $terms_lower[]=strtolower($v);
        $lower_searchstring = strtolower($search_string);
        
		foreach ($search as $key=>$value){
			// build sql first
			if ($search_cache_query !="") $search_cache_query.=" , ";
            
            // calculate how weight 
            $weight=0;
            $lower_body = strtolower($value->body);
            $lower_title = strtolower($value->title);
            foreach ($terms_lower as $k=>$v)
            {
                $weight += substr_count($lower_body, $v) + substr_count($lower_title, $v);
                if (count($terms)>1) // double weight if phase exist, for better result
                    $weight+=substr_count($lower_body, $lower_searchstring)*2 + substr_count($lower_title, $lower_searchstring)*2;
            }
            $value->weight = $weight;
            
			$search_cache_query.="({$search_id}, {$value->id}, {$weight})";
			// dont add search_item if size of search_temp is more than $config->max_item
			if (count($search_temp) < $config->max_item)
				$search_temp[$key]=$value;
		}
		$db->sql("INSERT INTO {$db->prefix}search_cache_result(query_id, result_id, weight) VALUES " . $search_cache_query);
		//
		$search=$search_temp;
	}
	// paging
	$pages=floor($search_cache->result_count / $config->max_item); 
	if ($search_cache->result_count % $config->max_item > 0)
		$pages++;
	if (($page<1) || ($page>$pages)) $page=1;
	$start_pos=($page-1)*($config->max_item);
	// end of paging
	if ($search == -1){ // reload the cache
		$search=$db->selectAndJoinObjects(null,null,"search","search_cache_result","id","result_id","query_id={$search_cache->id} ORDER BY weight DESC , category LIMIT {$start_pos},{$config->max_item}");
	}
	// get all sections in here to get faster search
	$sections_cache_t=$db->sql("SELECT id,name,parent FROM {$db->prefix}section");
	$sections_cache=array();
	for ($i = 0; $i < mysqli_num_rows($sections_cache_t); $i++)
	{
		$sections_cache_temp=mysqli_fetch_object($sections_cache_t);
		$sections_cache[$sections_cache_temp->id] =$sections_cache_temp; 
	}
	// end of 8/26/2009

	// this is the old school searching...once we implement FullText index in the DB subsystem we can use it instead.
	// to turn on FT seaching uncomment the foreach line below.
	foreach ($search as $key=>$r) {
		//foreach ($db->selectSearch($search_string) as $r) { 
		$result = null;

		if ($r->ref_type != 'section') {
			if ($r->location_data != "")
			{
				$rloc = unserialize($r->location_data);
				$sectionref = @$db->selectObject("sectionref","module='".$rloc->mod."' AND source='".$rloc->src."'");
				$section = @$db->selectObject("section","id=".$sectionref->section);
			}	
			else
			{
				$section=null;
			}
		} else {
			$section = $db->selectObject('section', 'id='.$r->original_id);
		}

		$canview = navigationmodule::canView($section);
		if ($r->location_data == "")
		{
			$canview=true;
		}
		if ($canview && $r->view_perm != '') {
			// No point in checking the perm stuff if they cant even see the section
			$canview = false; // They need to have specific perms on the module.
			foreach (explode(',',$r->view_perm) as $p) {
				if (exponent_permissions_check($p,$rloc)) {
					$canview = true;
					break;
				}
			}
		}

		if ($canview) {
			//$body_l = strtolower($r->body);
			//$title_l = strtolower($r->title);
			
			if ($r->category != 'Webpages') {
				if ($r->view_link == "") {
					// No viewlink - go to the page
					$result->view_link = exponent_core_makeLink(array("section"=>$sectionref->section));
				} else {
					$result->view_link = URL_FULL.$r->view_link;
				}

				// find title
				if ($r->title == "") {
					// No title - use site title and section name
					$section = $db->selectObject("section","id=".$sectionref->section);
					$result->title = $section->name . " :: " . SITE_TITLE;
				} else $result->title = $r->title;
			} else if ($r->ref_module == "textmodule")
				{
					$result->view_link = $r->view_link;
					$result->title = $r->title;  
				} 
				else{
					global $router;
					$result->view_link = $router->makeLink(array('section'=>$r->original_id));
					$result->title = $r->title;
			}

			if ($r->dont_trim ==0){
				$lastpos = 0;
				$first = 0;
				$last = 0;
				$halflen = 50;
				$lastfirst = -2*$halflen-1; // padding to be safe.
				$result->sum = "";
				while (strlen($result->sum) < 200) {
					$lastpos = stripos($r->body,$_REQUEST['search_string'],$lastpos);
					if ($lastpos === false) break;
					$first = $lastpos - $halflen;
					if ($first < 0) $first = 0;

					if ($first < $lastfirst + ($halflen*2)) { // inside the bounds of last chunk
						$first = $lastfirst + ($halflen*2);
					} else if ($first != 0) $result->sum .= " ... ";

						while ($first > 0 && substr($r->body,$first,1) != " ") $first--;
					$last = $first + (2*$halflen);
					if ($last > strlen($r->body)) $last = strlen($r->body);
					else while ($last > $first && substr($r->body,$last,1) != " ") $last--;

					$result->sum .= substr($r->body,$first,$last - $first);

					$lastpos++;
					$lastfirst = $first;
				}

				if ($last == $first && $first == 0) {
					$last = 300;
					if ($last > strlen($r->body)) $last = strlen($r->body);
					else while ($last > $first && substr($r->body,$last,1) != " ") $last--;

					$result->sum = substr($r->body,$first,$last);
				}
				if ($last < strlen($r->body)) $result->sum .= " ...";

				$result->sum = str_replace("\n","<br />",$result->sum);
				$result->no_title=0;
			}
			else {
				$result->sum = $r->body;
				$result->no_title=1;
			}

			$p_term_search  = array_map(create_function('$a','return "/([\s.,:;]{1}".$a."[\s.,:;$]{1})/i";'),$terms);
			$result->sum = preg_replace($p_term_search,"<b>\$1</b> ",$result->sum);
            $result->sum = str_replace("<br>","", $result->sum);
            $result->sum = str_replace("<br />","", $result->sum);

			//8/26/2009 : Immanuel192 write this code to get full address of each result
			$temp_loc=unserialize($r->location_data);
			// get section ID
			$temp=@$db->selectObject("sectionref"," (source = '{$temp_loc->src}') AND (module = '{$temp_loc->mod}')");
			$temp_path_array=array();
			if ($temp){
				$temp=$temp->section;
				$result->main_section=$temp;
				// loop to getback to root parent
				do {
					// get section name
					$my_object=null;
					$temp=$sections_cache[$temp];// get section cached
					$temp_item->name=$temp->name;
					$my_object->id=$temp->id;
					$my_object->name=$temp->name;
					$my_object->url=$router->buildUrlByPageId($my_object->id);
                    if (substr($my_object->url,0,1) != "/")
                        $my_object->url="/".$my_object->url;
					$temp_path_array[$temp->id]=$my_object;
					// for next loop
					$temp=$temp->parent;
					// mar 28, 2011 - trungdt - when parent = -1, it mean: this is root section
				} while (($temp != 0) & ($temp > -1));

				// revert array
				$temp_path_array=array_reverse($temp_path_array, true);
			}
			// 
			$result->sections=$temp_path_array;
			// add category to $result
			$result->category=strtolower($r->category);
			$result->ref_module=strtolower($r->ref_module);
            $result->id=$r->id;
			$result->view_link=str_replace(URL_FULL."/",URL_FULL, $result->view_link);
            $result->weight = $r->weight;
			// end 8/26/2009

			if ($config->is_categorized == 1) {
				if (!isset($results[$r->category])) {
					$results[$r->category] = array();
				}
				$results[$r->category][] = $result;
			} else {
				$results[] = $result;
			}
			//}
		}
	}
	// Feb 24, 2011 - trungdt - Add Title set - begin
    $title = exponent_lang_getText("search_title");
    $title = str_replace("%s", $search_string,$title);
	_ab_theme_action_register_title($title);
	// Feb 24, 2011 - trungdt - end
	$template = new template('searchmodule','_results');
	$template->assign('config',$config);
	$template->assign('query',$search_string);
	$template->assign('good_terms',$terms);
	$template->assign('excluded_terms',$term_status['excluded']);
	$template->assign('have_excluded_terms',count($term_status['excluded']));
	$template->assign('num_results',$search_cache->result_count);
	$template->assign('results',$results);
	//8/27/2009: immanuel192 write this code to calculate how long the search perform
	$template->assign('query_time',round(microtime()-$query_time_start,2));
	$template->assign('page',$page);
	$template->assign('pages',$pages);
	$template->assign('modules',$modules_list);
	$template->assign('search_type',isset($_REQUEST['search_type'])?$_REQUEST['search_type']:0);
	$template->assign('query_id',isset($search_cache->id)?$search_cache->id:'');
	// end 8/27/2009
	$template->output();
    exponent_sessions_set("AB_THEME_TOP_CONTAINER_SRC","top_searchmodule_".LANG);
    exponent_sessions_set("AB_THEME_TOP_CONTAINER_TYPE","textmodule");

?>
